/* Include these
   #include <stdint.h>
   #include <uuid/uuid.h>
   #include <nit/list.h>
   #include <nit/hset.h>
   #include <nit/hmap.h>
*/

enum ort_type { ORT_ARR, ORT_GAP, ORT_VEC };

typedef struct {
	const char *path;
	size_t path_size;
	Nit_hmap map;
	Nit_hentry *stack;
} Ort_base;

typedef struct {
	Ort_base *base;
	uuid_t id;
	size_t size;
        int freeable;
	enum ort_type type;
	char mem[];
} Ort_dat;

typedef void *Ort_ptr;

int
ort_base_init(Ort_base *base, const char *path);

void
ort_base_dispose(Ort_base *base);

Ort_base *
ort_base_new(const char *path);

void
ort_base_free(Ort_base *base);

/* Dat allocation and deallocation */

int
ort_dat_init(Ort_dat *dat, Ort_base *base, size_t size);

int
ort_dat_init0(Ort_dat *dat, Ort_base *base, size_t size);

void
ort_dat_revoke(Ort_dat *dat);

static inline void
ort_dat_dispose(Ort_dat *dat)
{
	ort_dat_revoke(dat);
}

Ort_dat *
ort_dat_new(Ort_base *base, size_t size);

Ort_dat *
ort_dat_new0(Ort_base *base, size_t size);

void
ort_dat_free(Ort_dat *dat);

/* Mem allocation and deallocation */

Ort_ptr
ort_alloc(Ort_base *base, size_t size);

Ort_ptr
ort_alloc0(Ort_base *base, size_t size);

void
ort_free(Ort_ptr mem);

Ort_ptr
ort_init(Ort_base *base, void *dat, size_t size);

Ort_ptr
ort_init0(Ort_base *base, void *dat, size_t size);

void
ort_revoke(Ort_ptr mem);

static inline void
ort_dispose(Ort_ptr mem)
{
	ort_revoke(mem);
}

/* loading from base */

int
ort_dat_load_to(Ort_dat *dat, Ort_base *base, uuid_t id);

Ort_dat *
ort_dat_load(Ort_base *base, uuid_t id);

Ort_ptr
ort_load_to(Ort_base *base, void *mem, uuid_t id);

Ort_ptr
ort_load(Ort_base *base, uuid_t id);

/* saving state */

int
ort_dat_save(Ort_dat *dat);

int
ort_save(Ort_ptr mem);

/* Utilities */
Ort_ptr
ort_ptr(Ort_base *base, uuid_t id);

void
ort_id(uuid_t id, Ort_ptr mem);

size_t
ort_size(Ort_ptr mem);

Ort_dat *
ort_dat(Ort_ptr mem);

void
ort_destruct(Ort_ptr mem);
